/** \file
* Implementation of the main application class.
* This file is part of Chorus, available at
* http://code.google.com/p/chorus-twitter/ . This file and all associated files
* and derivative works are bound by the terms of the LGPL 3.0 license,
* available at http://www.gnu.org/licenses/lgpl-3.0-standalone.html .
* \par Subversion URL:
* \$URL: http://chorus-twitter.googlecode.com/svn/branches/cpp/src/app/ChorusApp.cpp $
* \version \$Rev: 152 $
* \date    \$Date: 2010-04-06 07:35:13 +0000 (Tue, 06 Apr 2010) $
*/

#include "config.h"

#include <libxml/parser.h>

#include "system/DebugConsole.hpp"

#include "xml/XmlFileSource.hpp"
#include "xml/XmlUrlSource.hpp"

#include "app/ChorusApp.hpp"

using namespace std;

ChorusApp::ChorusApp()
{
	// Clear the database pointers.
	statuses = 0;
	users = 0;
	dms = 0;

	PDEBUG("Construction started...");

	// Initialize the libxml parser.
	xmlInitParser();

	// Instantiate the curl globals class.
	curlglob = new CurlGlob;
	if (!curlglob)
	{
		PDEBUG("new failed");
		return;
	}

	// Instantiate the databases.

	statuses = new StatusTree(curlglob);
	if (!statuses)
	{
		PDEBUG("new failed");
		return;
	}

	users = new UserTree(curlglob);
	if (!users)
	{
		PDEBUG("new failed");
		return;
	}

	statuses->setUserTree(users);
	users->setStatusTree(statuses);

	dms = new DMTree(curlglob);
	if (!dms)
	{
		PDEBUG("new failed");
		return;
	}

	if (!load())
		return;

	PDEBUG("Construction successful.");
}

ChorusApp::~ChorusApp()
{
	PDEBUG("Destruction started...");

	// Wait for the rest of the threads.
	Thread::waitAllThenAbort(20000);

	// Free the databases.

	if (statuses)
	{
		if (users)
			users->setStatusTree(0);
		delete statuses;
		statuses = 0;
	}
	if (users)
	{
		delete users;
		users = 0;
	}
	if (dms)
	{
		delete dms;
		dms = 0;
	}

	// Free the curl globals instance.
	if (curlglob)
	{
		delete curlglob;
		curlglob = 0;
	}

	// Shut down libxml.
	xmlCleanupParser();

	PDEBUG("Destruction done.");
}

bool ChorusApp::load()
{
	// Load the initial XML data.
	if (!statuses->load())
		return false;
	if (!users->load())
		return false;
	if (!dms->load())
		return false;
	return true;
}

bool ChorusApp::update()
{
	// Update the XML data from the web.
	if (!statuses->update())
		return false;
	if (!users->update())
		return false;
	if (!dms->update())
		return false;
	return true;
}

bool ChorusApp::save()
{
	// Save the XML data locally.
	if (!statuses->save())
		return false;
	if (!users->save())
		return false;
	if (!dms->save())
		return false;
	return true;
}
